package com.xc.stock.domain.basic.entity;

import java.math.BigDecimal;
import java.util.Date;

import com.ag.exception.SysTipsException;
import com.ag.utils.BigDecimals;
import com.ag.utils.Jsons;
import com.ag.utils.NumberUtils;
import com.ag.utils.SysConstant.ProgressEnum;
import com.alibaba.fastjson.JSONObject;
import com.xc.stock.constant.AccountActionEnum;
import com.xc.stock.dto.model.AccountOperParam;
import com.xc.stock.infrastructure.db.po.AccountActionPO;

import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;

/**
 * AccountAction 
 *
 * @author xlfd 
 * @email xlfd@gmail.com 
 * @created 2022/03/25 
 */
@Data
@NoArgsConstructor
@SuperBuilder
@EqualsAndHashCode(
    callSuper = false
)
public class AccountAction extends AccountActionPO {
	public void checkCanOper() {
		if(NumberUtils.equals(getActionStatus(), ProgressEnum.FAIL.v())
				|| NumberUtils.equals(getActionStatus(), ProgressEnum.SUCCESS.v())) {
			throw new SysTipsException("该账户动作不可操作");
		}
	}
	
	
	
	void fr(String msg) {
		BigDecimal fr = BigDecimals.add(getRefund(), getFinish());
		
		if(BigDecimals.lt(getAmount().abs(), fr.abs())) {
			throw new SysTipsException(String.format("该账户动作不可操作, 已经超过可操作金额总金额[%s], FR:[%s]", getAmount(), fr));
		} else if(BigDecimals.eq(getAmount(), fr)) {
			if(BigDecimals.neZero(getFinish())) {
				setActionStatus(ProgressEnum.SUCCESS.v());
			} else {
				setActionStatus(ProgressEnum.FAIL.v());
				JSONObject j = Jsons.toJSONAnyway(getExt());
				j.put("failMsg", msg);
				setExt(j.toJSONString());
			}
		}
	}
	
	public void finish(BigDecimal finish) {
		checkCanOper();
		setFinish(BigDecimals.add(getFinish(), finish));
		
		fr(null);
	}
	
	public void refund(BigDecimal amount, String msg) {
		checkCanOper();
		setRefund(BigDecimals.add(getRefund(), amount));
		
		fr(msg == null ? "扣款到0了" : msg);
	}
	
	public AccountOperParam accountOperParam() {
		AccountAction aa = this;
		AccountOperParam build = AccountOperParam.builder()
				.accountAction(AccountActionEnum.of(aa.getAction()))
				.outerUid(aa.getOuterUid())
				.outerNo(aa.getOuterUid())
				.logContent(aa.getLogContent())
				.logExt(Jsons.toJSONAnyway(aa.getExt()))
				.stampTax(ext("stampTax", BigDecimal.ZERO))
				.commission(ext("commission", BigDecimal.ZERO))
				.recharge(ext("recharge", BigDecimal.ZERO))
				.preTradingDay(ext("preTradingDay", BigDecimal.ZERO))
				.withdrawAmount(ext("withdrawAmount", BigDecimal.ZERO))
				.build();
		return build;
	}

	public void putExt(String k, Object v) {
		JSONObject json = Jsons.toJSONAnyway(getExt());
		json.put(k, v);
		setExt(json.toJSONString());
	}
	
	public <T> T ext(String k, Class<T> clazz) {
		return Jsons.getByPath(getExt(), k, clazz);
	}
	
	public <T> T ext(String k, T t) {
		return Jsons.getByPath(getExt(), k, t);
	}


	/**
	 * 剩余未操作的
	 * @return
	 */
	public BigDecimal remaining() {
		return BigDecimals.subtract(getAmount(), getFinish(), getRefund());
	}

	public void limitWithrawPass() {
		setLimitWithdrawStatus(ProgressEnum.SUCCESS.v());
		putExt("limitWithrawPassDate", new Date());
	}
}
